using System;
using BitBenderGames;
using UnityEngine;
using XLua;
using Yoozoo.Framework.Managers;

namespace Yoozoo.Gameplay.City
{
    public class City2dTouchManager : MonoBehaviour
    {
        public TouchInputController touchInputController;
        private MobileTouchCamera m_mobileTouchCamera;

        private LuaEnv m_LuaState;
        
        public const string LUAFunctionName_OnTouchStart = "L_City2dTouchManager.OnTouchStart";
        public const string LUAFunctionName_OnTouchUp = "L_City2dTouchManager.OnTouchUp";
        public const string LUAFunctionName_On_SimpleTap = "L_City2dTouchManager.OnSimpleTap";
        public const string LUAFunctionName_OnDragStart = "L_City2dTouchManager.OnDragStart";
        public const string LUAFunctionName_OnDoubleDragStart = "L_City2dTouchManager.OnDoubleDragStart";
        public const string LUAFunctionName_OnDrag = "L_City2dTouchManager.OnDrag";
        public const string LUAFunctionName_OnDoubleDrag = "L_City2dTouchManager.OnDoubleDrag";
        public const string LUAFunctionName_OnDragEnd = "L_City2dTouchManager.OnDragEnd";
        public const string LUAFunctionName_OnDoubleDragEnd = "L_City2dTouchManager.OnDoubleDragEnd";
        public const string LUAFunctionName_OnDoubleTap = "L_City2dTouchManager.OnDoubleTap";
        public const string LUAFunctionName_OnTouchDown = "L_City2dTouchManager.OnTouchDown";
        public const string LUAFunctionName_OnFingerUpLastOne = "L_City2dTouchManager.OnFingerUpLastOne";
        
        public const string LUAFunctionName_OnScrollEnd = "L_City2dTouchManager.OnScrollEnd";
        public const string LUAFunctionName_OnInertiaOver = "L_CityEventMgr.onInertiaOver";


        private LuaFunction luaOnTouchStart;
        private LuaFunction luaOnTouchUp;
        private LuaFunction luaOnSimpleTap;
        private LuaFunction luaOnDragStart;
        private LuaFunction luaOnDoubleDragStart;
        private LuaFunction luaOnDrag;
        private LuaFunction luaOnDoubleDrag;
        private LuaFunction luaOnDragEnd;
        private LuaFunction luaOnDoubleDragEnd;
        private LuaFunction luaOnDoubleClick;
        private LuaFunction luaOnFingerUpLastOne;        // 当只剩一根手指在屏幕
        
        private LuaFunction luaOnTouchDown;
        
        private LuaFunction luaOnScrollEnd;        // 滑动停止
        private LuaFunction luaOnInertiaOver;

        public void Initialize(MobileTouchCamera mobileTouchCamera)
        {

            m_mobileTouchCamera = mobileTouchCamera;
            touchInputController = m_mobileTouchCamera.TouchInputController;

            m_LuaState = LuaManager.mainState;
            if (m_LuaState == null)
            {
                throw new Exception("LuaManager is null");
            }

            luaOnTouchStart = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnTouchStart);
            luaOnTouchUp = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnTouchUp);
            luaOnSimpleTap = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_On_SimpleTap);
            luaOnDragStart =  m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnDragStart);
            luaOnDoubleDragStart =  m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnDoubleDragStart);
            luaOnDrag = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnDrag);
            luaOnDoubleDrag = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnDoubleDrag);
            luaOnDragEnd = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnDragEnd);
            luaOnDoubleDragEnd = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnDoubleDragEnd);
            luaOnDoubleClick = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnDoubleTap); 
            luaOnTouchDown = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnTouchDown);
            luaOnFingerUpLastOne = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnFingerUpLastOne);
            luaOnScrollEnd = m_LuaState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnScrollEnd);
            luaOnInertiaOver = LuaManager.mainState.Global.GetInPath<LuaFunction>(LUAFunctionName_OnInertiaOver);

            touchInputController.OnInputClick += On_TouchClick;
            touchInputController.OnFingerUp += On_TouchUp;
            touchInputController.OnFingerDown += On_TouchStart;
            touchInputController.OnTouchDown += On_TouchDown;
            touchInputController.OnDragStart += On_DragStart;
            //touchInputController.OnDoubleDragStart += On_DoubleDragStart;
            touchInputController.OnDragUpdate += On_Drag;
            //touchInputController.OnDoubleDragUpdate += On_DoubleDrag;
            touchInputController.OnDragStop += On_DragEnd;
            //touchInputController.OnDoubleDragStop += On_DoubleDragEnd;

            touchInputController.OnFingerUpLastOne += On_FingerUpLastOne;
            touchInputController.OnScrollEnd += On_ScrollEnd;
            m_mobileTouchCamera.OnInertiaOver += On_InertiaOver;
        }

        public void Destroy()
        {
            touchInputController.OnInputClick -= On_TouchClick;
            touchInputController.OnFingerUp -= On_TouchUp;
            touchInputController.OnFingerDown -= On_TouchStart;
            touchInputController.OnTouchDown -= On_TouchDown;
            touchInputController.OnDragStart -= On_DragStart;
            //touchInputController.OnDoubleDragStart -= On_DoubleDragStart;
            touchInputController.OnDragUpdate -= On_Drag;
            //touchInputController.OnDoubleDragUpdate -= On_DoubleDrag;
            touchInputController.OnDragStop -= On_DragEnd;
            //touchInputController.OnDoubleDragStop -= On_DoubleDragEnd;

            touchInputController.OnFingerUpLastOne -= On_FingerUpLastOne;
            touchInputController.OnScrollEnd -= On_ScrollEnd;
            m_mobileTouchCamera.OnInertiaOver -= On_InertiaOver;
        }

        public void SwitchTouchInput(bool active)
        {
            touchInputController.enabled = active;
        }

        public bool GetTouchInputState()
        {
            return touchInputController.enabled;
        }
        
        private bool GetRayCast(Vector3 clickPosition, out RaycastHit hitInfo)
        {
            Ray camRay = m_mobileTouchCamera.Cam.ScreenPointToRay(clickPosition);
            if (Physics.Raycast(camRay, out hitInfo))
            {
                return true;
            }
            return false;
        }

        private RaycastHit[] GetRayCastAll(Vector3 clickPosition)
        {
            Ray camRay = m_mobileTouchCamera.Cam.ScreenPointToRay(clickPosition);
            var all = Physics.RaycastAll(camRay);
            return all;
        }

        private void On_FingerUpLastOne(Vector3 fingerPos, bool isonui)
        {
            RaycastHit hitInfo;
            GetRayCast(fingerPos, out hitInfo);
            luaOnFingerUpLastOne.Action(fingerPos, hitInfo);
        }


        private void On_TouchClick(Vector3 clickPosition, bool isdoubleclick, bool islongtap,bool isOnUI)
        {
            bool isSelectedUi = TouchInputController.mLastSelectedUi != null;
            
            RaycastHit hitInfo;
            GetRayCast(clickPosition, out hitInfo);
            if (isdoubleclick)
            {
                luaOnDoubleClick.Action(clickPosition,hitInfo,isOnUI,isSelectedUi,islongtap);
            }
            else
            {
                var allHitInfo =  GetRayCastAll(clickPosition);
                luaOnSimpleTap.Action(clickPosition, hitInfo,isOnUI,isSelectedUi,islongtap, allHitInfo);
            }
        }

        private void On_TouchUp()
        {
            luaOnTouchUp.Call();
        }
        
        
        private void On_TouchStart(Vector3 clickPosition,bool isOnUI)
        {
            //
            RaycastHit[] hitInfos = GetRayCastAll(clickPosition);
            if (hitInfos.Length > 0)
            {
                luaOnTouchStart.Action(clickPosition, hitInfos[0], isOnUI, hitInfos);
            }
            else
            {
                luaOnTouchStart.Action(clickPosition, default(RaycastHit), isOnUI, hitInfos);
            }
        }
        
        private void On_TouchDown(float holdTime,bool isOnUI)
        {
            luaOnTouchDown.Action(holdTime,isOnUI);
        }

        public void On_ScrollEnd()
        {
            luaOnScrollEnd.Call();
        }

        private void On_DragEnd(Vector3 dragstoppos, Vector3 dragfinalmomentum)
        {
            RaycastHit hitInfo;
            GetRayCast(dragstoppos, out hitInfo);
            luaOnDragEnd.Action(dragstoppos, hitInfo);
        }
        
        private void On_DoubleDragEnd(Vector3 dragstoppos, Vector3 dragfinalmomentum)
        {
            RaycastHit hitInfo;
            GetRayCast(dragstoppos, out hitInfo);
            luaOnDoubleDragEnd.Action(dragstoppos, hitInfo);
        }

        private void On_Drag(Vector3 dragposstart, Vector3 dragposcurrent, Vector3 correctionoffset,bool isOnUI)
        {
            RaycastHit hitInfo;
            GetRayCast(dragposcurrent, out hitInfo);
            luaOnDrag.Action(dragposcurrent, hitInfo, isOnUI);
        }
        
        private void On_DoubleDrag(Vector3 dragposstart, Vector3 dragposcurrent, Vector3 correctionoffset,bool isOnUI)
        {
            RaycastHit hitInfo;
            GetRayCast(dragposcurrent, out hitInfo);
            luaOnDoubleDrag.Action(dragposcurrent, hitInfo, isOnUI);
        }
        
        

        private void On_DragStart(Vector3 pos, bool islongtap,bool isOnUI)
        {
            RaycastHit hitInfo;
            GetRayCast(pos, out hitInfo);
            luaOnDragStart.Action(pos, hitInfo, isOnUI);
        }
        private void On_DoubleDragStart(Vector3 pos, bool islongtap,bool isOnUI)
        {
            RaycastHit hitInfo;
            GetRayCast(pos, out hitInfo);
            luaOnDoubleDragStart.Action(pos, hitInfo, isOnUI);
        }

        private void On_InertiaOver()
        {
            luaOnInertiaOver?.Action();
        }

    }
}